/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.gov.cemaden.imagefilter.watcher;

import br.gov.cemaden.imagefilter.concurrent.FilterCallable;
import br.gov.cemaden.imagefilter.repository.XMLRepositoryReader;
import br.gov.cemaden.imagefilter.repository.RepositoryReader;
import br.gov.cemaden.watcher.FileWatcherRepeat;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
import org.apache.log4j.Logger;

/**
 *
 * @author Jether
 */
public class ImageAPIWatcher extends FileWatcherRepeat {

    private String source, pathTarget;
    private int option;    
    private Map<String, String> values;
    ExecutorService executorPool;
    Collection<FilterCallable> threads;
    
    private Logger logger = Logger.getLogger(ImageAPIWatcher.class.getName());

    public ImageAPIWatcher(String dirName, String pathTarget, int option, boolean recursive, boolean procExistents) {
        
        super(dirName, recursive, procExistents);
        
        this.pathTarget = pathTarget;
        this.source = dirName;       
        this.option = option;
        
        RepositoryReader reader = new XMLRepositoryReader(getProperty("repository"));
        values = reader.getElements();
        
        if( values.isEmpty() ){
            throw new RuntimeException("Values are empty!");
        }        
        
        executorPool = new ThreadPoolExecutor(8, 10, 10, 
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(values.size()), 
                Executors.defaultThreadFactory());        
        
        threads = new ArrayList<FilterCallable>();
    }        

    @Override
    public boolean handleCreate(Path path) {
        return handleModify(path);
    }

    @Override
    public boolean handleModify(Path path) {        
        
        String filename = path.getFileName().toString();
        
        for (Map.Entry<String, String> entry : values.entrySet()) {
            
            if( filename.matches( "^" + entry.getValue() + ".*" ) ){                
                
                // Uses Callable interface and return the result expected, in this case, a Boolean
                try{
                    return executorPool.submit(new FilterCallable(path.toString(), pathTarget, entry.getKey(), option)).get();
                }
                catch(ExecutionException e){
                    System.err.println("Error when executing the filter: " + e.getMessage());
                    e.printStackTrace();
                }
                catch(InterruptedException e){
                    System.err.println("The filter thread was interrupted: " + e.getMessage());
                    e.printStackTrace();
                }
            }
        }                       
        
        return false;
    }
    
    /**
     * 
     * @param property
     * @return 
     */
    private String getProperty( String property ){
        try {
            Properties props = new Properties();
            InputStream in = this.getClass().getResourceAsStream("/resources/conf.properties");
            props.load(in);
            in.close();
            return props.getProperty(property);
        }
        catch( FileNotFoundException e ){
            e.printStackTrace();
        }
        catch( IOException e ){
            e.printStackTrace();
        }
        return "";
    }
}
